const Koa = require("koa"); // 导入koa
const koaBody = require("koa-body");
const error = require("koa-json-error");
const parameter = require("koa-parameter");
const koaStatic = require("koa-static");
const path = require("path");
const cors = require("koa2-cors");
const mongoose = require("mongoose");
const { port, connectMongodbKey, checkRight } = require("./config");
const routing = require("./routes");
const checkRightMiddle = require("../middlewares/checkRight");
const socket = require("koa-websocket");
const cacheControl = require("koa-cache-control");
// const logs = require('../middlewares/logs');
// const User = require("./models/user");
// const Env = require("./models/env");
const fs = require("fs");
const { v4: uuidv4 } = require("uuid");

mongoose.connect(
  connectMongodbKey,
  { useUnifiedTopology: true, useNewUrlParser: true },
  () => {
    console.log("Mongodb connect Success OK");
  }
);
mongoose.connection.on("error", console.error);

const app = socket(new Koa()); // 实例化koa
app.ws.use(function (ctx, next) {
  ctx.websocket.send("open");
  return next(ctx);
});

app.use(
  cacheControl({
    maxAge: 5 * 3600,
  })
);

// app.use(async (ctx, next) => {
//   if (ctx.header.authorization && ctx.request.url !== "/users/login") {
//     const acc = await Env.findOne({ name: "Login-Type" });
//     if (acc && acc.value * 1 === 1) {
//       const token = ctx.header.authorization.split(" ")[1];
//       const user = await User.findOne({
//         token: token,
//       });

//       if (!user || (user && user.token !== token)) {
//         ctx.body = {
//           errCode: 401,
//         };
//         return;
//       }
//     }
//   }
//   try {
//     await next();
//   } catch (err) {
//     ctx.status = err.status || err.statusCode || 500;
//     ctx.body = {
//       msg: err.message,
//     };
//   }
// });

app.use(koaStatic(path.join(__dirname, "public")));

// app.use(error({
//     postFormat: (e, {stack, ...rest}) => process.env.NODE_ENV === 'production' ? rest : {stack, ...rest}
// }));

// 跨域
app.use(
  cors({
    origin: function (ctx) {
      //设置允许来自指定域名请求
      if (!ctx.header.referer) return;
      const whiteList = [
        "http://weipxiu.com",
        "http://192.168.60.91:8080",
        "http://192.168.68.53:3000",
        "http://192.168.68.53:3001",
        "http://192.168.3.23:3000",
      ]; //可跨域白名单
      let url = ctx.header.referer.substr(0, ctx.header.referer.length - 1);
      if (whiteList.includes(url)) {
        return url; //注意，这里域名末尾不能带/，否则不成功，所以在之前我把/通过substr干掉了
      }
      return "http://localhost:3000"; //默认允许本地请求3000端口可跨域
    },
    maxAge: 5, //指定本次预检请求的有效期，单位为秒。
    credentials: true, //是否允许发送Cookie
    allowMethods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"], //设置所允许的HTTP请求方法
    allowHeaders: ["Content-Type", "Authorization", "Accept"], //设置服务器支持的所有头信息字段
    exposeHeaders: ["WWW-Authenticate", "Server-Authorization"], //设置获取其他自定义字段
  })
);

// const scheduleTask = require("./controllers/schedule");
// const schedule = require("node-schedule");
// const rule = new schedule.RecurrenceRule();
// rule.minute = [0, 15, 30, 45];
// schedule.scheduleJob(rule, function () {
//   console.log("scheduleCronstyle:" + new Date());
//   scheduleTask.getUserOnline();
// });

app.use(
  error({
    postFormat: (e, { stack, ...rest }) => {
      if (rest.status === 404) {
        return " ";
      } else {
        if (process.env.NODE_ENV === "production") {
          return {
            errCode: rest.errCode,
            msg: rest.message,
            data: rest.data,
          };
        } else {
          return {
            stack: stack,
            errCode: rest.errCode,
            msg: rest.message,
            data: rest.data,
          };
        }
      }
    },
  })
);

app.use(
  koaBody({
    multipart: true, // 开启文件上传
    formidable: {
      uploadDir: path.join(__dirname, "/public/uploads"), // 使用Node自带的path设置文件上传路径
      keepExtensions: true, // 是否保留文件的拓展名,是
      maxFileSize: 20000 * 1024 * 1024, // 设置上传文件大小最大限制20G
      onFileBegin: (name, file) => {
        if (name === "editorFile") {
          // 最终要保存到的文件夹目录
          const dir = path.join(__dirname, `public/editor`);
          // 检查文件夹是否存在如果不存在则新建文件夹
          if (!fs.existsSync(dir)) {
            fs.mkdirSync(dir);
          }
          // 文件名称去掉特殊字符但保留原始文件名称
          const uuid = uuidv4({ format: "hex" });
          const fileName = "editor." + uuid + "." + file.name;
          file.name = fileName;
          // 覆盖文件存放的完整路径(保留原始名称)
          file.path = `${dir}/${fileName}`;
        } else if (name.indexOf("resources") > -1) {
          // 最终要保存到的文件夹目录
          const folder = name.toLowerCase();
          const dir = path.join(__dirname, `public/${folder}`);
          // 检查文件夹是否存在如果不存在则新建文件夹

          if (!fs.existsSync(dir)) {
            fs.mkdirSync(dir);
          }
          // 文件名称去掉特殊字符但保留原始文件名称
          const fileName = file.name;
          file.name = fileName;
          // 覆盖文件存放的完整路径(保留原始名称)
          file.path = `${dir}/${fileName}`;
          file.folder = folder.replace(/resources\//g, "");
        }
      },
      onError: (error) => {
        app.status = 400;
        log4js.error(error);
        // 这里可以定义自己的返回内容
        app.body = { errCode: -1, msg: "上传失败", data: {} };
        return;
      },
    },
  })
);

app.use(parameter(app));
if (checkRight) {
  app.use(checkRightMiddle);
}
// app.use(logs);
routing(app);

module.exports = app;
